package com.yun.zf.system.service.impl;

import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yun.zf.common.admin.domain.SysDept;
import com.yun.zf.common.admin.model.sys.DeptAddMo;
import com.yun.zf.common.admin.model.sys.DeptEditMo;
import com.yun.zf.common.admin.model.sys.DeptSearchMo;
import com.yun.zf.common.app.domain.ZfCity;
import com.yun.zf.common.constant.UserConstants;
import com.yun.zf.common.mapstruct.admin.SysMapper;
import com.yun.zf.common.utils.StringUtils;
import com.yun.zf.system.exception.CustomException;
import com.yun.zf.system.mapper.SysDeptMapper;
import com.yun.zf.system.service.ISysDeptService;
import com.yun.zf.system.service.SysAgentService;
import com.yun.zf.system.service.ZfCityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept> implements ISysDeptService {
    @Autowired
    private SysDeptMapper deptMapper;
    @Autowired
    private ZfCityService cityService;
    @Autowired
    private SysAgentService agentService;

    @Override
    public SysDept getParentId(long parentId) {
        QueryWrapper<SysDept> deptQueryWrapper = new QueryWrapper<>();
        deptQueryWrapper.lambda().eq(SysDept::getDeptId, parentId);
        return baseMapper.selectOne(deptQueryWrapper);
    }


    @Override
    public IPage<SysDept>  getDeptTree(DeptSearchMo deptMo) {
        QueryWrapper<SysDept> deptQueryWrapper = new QueryWrapper<>();
            if ( deptMo.getDeptId()!=null&& deptMo.getDeptId()>0){
                deptQueryWrapper.lambda().eq(SysDept::getDeptId, deptMo.getDeptId())
                        .eq(StringUtils.isNotEmpty(deptMo.getStatus()), SysDept::getStatus, deptMo.getStatus());
            }else {
                deptQueryWrapper.lambda().eq(StringUtils.isNotEmpty(deptMo.getStatus()), SysDept::getStatus, deptMo.getStatus())
                        .eq(SysDept::getLevel,1)
                        .eq(StringUtils.isNotBlank(deptMo.getCityCode()), SysDept::getCityCode, deptMo.getCityCode())
                        .eq(StringUtils.isNotBlank(deptMo.getProvinceCode()), SysDept::getProvinceCode, deptMo.getProvinceCode());
            }
        Page<SysDept> page = new Page<>(deptMo.getCurrent(), deptMo.getPageSize());
        IPage<SysDept> deptPage= baseMapper.selectPage(page,deptQueryWrapper);
        // 获取分页数据后，查询分页数据下的子部门，然后在进行重新赋值
        if (deptPage.getTotal()>0){
            List<SysDept> records = new ArrayList<>();
            for ( SysDept dept : deptPage.getRecords()
                 ) {
              List<SysDept> deptList=  this.getDeptsByParent(dept.getDeptId());
              dept.setChildren(deptList);
                records.add(dept);
            }
            deptPage.setRecords(records);
        }
        return deptPage;
    }


    @Override
    public List<Tree<String>> editDeptTree(List<SysDept> depts, int deep) {
        List<TreeNode<String>> nodeList = depts.stream().map(dept -> {
            Map<String, Object> map = new HashMap<>();
            TreeNode<String> treeNode = new TreeNode<String>().setId(dept.getDeptId().toString())
                    .setName(dept.getDeptName())
                    .setParentId(dept.getParentId().toString())
                    .setWeight(dept.getLevel())
                    .setExtra(map);
            return treeNode;
        }).collect(Collectors.toList());
        TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
        treeNodeConfig.setIdKey("value");
        treeNodeConfig.setNameKey("label");
        treeNodeConfig.setWeightKey("level");
        treeNodeConfig.setDeep(deep);

        List<Tree<String>> treeList = TreeUtil.build(nodeList, "0", treeNodeConfig,
                (treeNode, tree) -> {
                    tree.setId(treeNode.getId().toString());
                    tree.setParentId(treeNode.getParentId().toString());
                    tree.setName(treeNode.getName());
                    tree.setWeight(treeNode.getWeight());
                });

        return treeList;
    }


    /**
     * 校验部门名称是否唯一
     *
     * @return 结果
     */
    @Override
    public String checkDeptNameUnique(Long deptId, Long parentId, String deptName) {
        SysDept info = this.checkDepBynameid(parentId, deptName);
        if (StringUtils.isNotNull(info) && info.getDeptId().longValue() != deptId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    public SysDept checkDepBynameid(Long parentId, String deptName) {
        QueryWrapper<SysDept> deptQueryWrapper = new QueryWrapper<>();
        deptQueryWrapper.lambda().eq(SysDept::getDeptName, deptName)
                .eq(SysDept::getParentId, parentId);
        return baseMapper.selectOne(deptQueryWrapper);
    }

    @Override
    public int updateDept(DeptEditMo dept) {
        QueryWrapper<SysDept> deptQueryWrapper = new QueryWrapper<>();
        deptQueryWrapper.lambda().eq(SysDept::getDeptId, dept.getDeptId());
        SysDept dp = baseMapper.selectOne(deptQueryWrapper);
        if (StringUtils.isNotBlank(dept.getDeptName())) {
            dp.setDeptName(dept.getDeptName());
        }
        if (StringUtils.isNotBlank(dept.getLeader())) {
            dp.setLeader(dept.getLeader());
        }
        if (StringUtils.isNotBlank(dept.getPhone())) {
            dp.setPhone(dept.getPhone());
        }
        if (StringUtils.isNotBlank(dept.getEmail())) {
            dp.setEmail(dept.getEmail());
        }
        // 如果parentId 跟原数据保持不一致，则重新赋值parentId 和parentName
        if (dept.getParentId() != null && dept.getParentId().longValue() != dp.getParentId().longValue()) {
            SysDept parentDept = this.getParentId(dept.getParentId());
            if (parentDept != null) {
                dp.setParentId(dept.getParentId());
                dp.setParentName(parentDept.getDeptName());
            }
        }
        if (dp.getStatus() != dept.getStatus()) {
            dp.setStatus(dept.getStatus());
        }
        return baseMapper.update(dp, deptQueryWrapper);
    }

    /**
     * 新增部门
     *
     * @param dept
     * @return
     */
    @Override
    public int insertDept(DeptAddMo dept) {
        Long parentId = StringUtils.isNull(dept.getParentId()) ? 0L : dept.getParentId();
        // 验证当前分公司下是否存在此部门
        if (UserConstants.NOT_UNIQUE.equals(this.checkDeptNameUnique(-1L, parentId, dept.getDeptName()))) {
            return -1;
        }

        SysDept sysDept = SysMapper.INSTANCE.moToDept(dept);

        // 获取城市名称
        ZfCity city = cityService.getCity(dept.getCityCode());
        if (city==null || !dept.getProvinceCode().equals(city.getPid()) ){
            throw  new CustomException("未查询到城市数据");
        }
        sysDept.setProvinceName(city.getOneLevelName());
        sysDept.setCityName(city.getCityName());

        // 如果parentId 不为空
        if (parentId == 0) {
            sysDept.setLevel(1);
        }
        SysDept dp = this.getParentId(dept.getParentId());
        if (dp != null) {
            if (!dp.getParentId().equals(0L)) {
                throw new CustomException("不允许添加三级合作伙伴");
            }
            sysDept.setLevel(2);
            sysDept.setParentName(dp.getDeptName());
        }
        SysDept sdpt = this.getLastOrder(sysDept.getParentId());
        if (sdpt != null) {
            sysDept.setOrderNum(sdpt.getOrderNum() + 1);
        } else {
            sysDept.setOrderNum(0);
        }
        sysDept.setCreateTime(new Date());


        // 获取排序
        return baseMapper.insert(sysDept);
    }


    /**
     * 获取统一个父节点下的最后一个数据
     *
     * @param parentId
     * @return
     */
    @Override
    public SysDept getLastOrder(long parentId) {
        QueryWrapper<SysDept> deptQueryWrapper = new QueryWrapper<>();
        deptQueryWrapper.lambda().eq(SysDept::getParentId, parentId)
                .orderByDesc(SysDept::getOrderNum);
        List<SysDept> depts = baseMapper.selectList(deptQueryWrapper);
        if (depts.size() > 0) {
            return depts.get(0);
        } else
            return null;
    }

    @Override
    public SysDept getDeptByDeptId(Long deptId) {
        QueryWrapper<SysDept> deptQueryWrapper = new QueryWrapper<>();
        deptQueryWrapper.lambda().eq(SysDept::getDeptId, deptId);
        return baseMapper.selectOne(deptQueryWrapper);
    }


    @Override
    //@DataScope(deptAlias = "d")
    public List<SysDept> selectDeptList(Long provinceCode,Long cityCode) {
       QueryWrapper<SysDept> deptQueryWrapper = new QueryWrapper<>();
       deptQueryWrapper.lambda().eq(SysDept::getCityCode,cityCode)
               .eq(SysDept::getProvinceCode,provinceCode);

      return   baseMapper.selectList(deptQueryWrapper);
    }



    @Override
    public void changeStatus(Long deptId, int status, int level) {
        Long parentId = 0L;
        if (level == 1) {
            parentId = deptId;
        }

        baseMapper.changeStatus(deptId, status, parentId);
    }

    @Override
    public List<SysDept> getDeptsByParent(Long parentId) {
        QueryWrapper<SysDept> deptQueryWrapper = new QueryWrapper<>();
        deptQueryWrapper.lambda().eq(SysDept::getParentId,parentId);
        return baseMapper.selectList(deptQueryWrapper);
    }
}


